package cn.like.satoken.core;

import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
import cn.dev33.satoken.stp.StpInterface;
import cn.hutool.json.JSONUtil;
import cn.like.common.context.redisKey.AuthRedisKey;
import cn.like.feign.AuthUserFeignService;
import cn.like.function.Func;

import java.util.List;

/**
 * desc:
 * 自定义权限验证接口扩展
 * <pre>
 *     获取用户的权限以及角色
 * </pre>
 *
 * @author like 980650920@qq.com
 * @date 2021-07-10 08:54:20
 * @see StpInterface
 */
public class PermissionAndRoleInformation implements StpInterface {

    // Inject
    public final SaTokenDaoRedisJackson saTokenDaoRedisJackson;
    public final AuthUserFeignService authUserFeignService;

    public PermissionAndRoleInformation(SaTokenDaoRedisJackson saTokenDaoRedisJackson, AuthUserFeignService authUserFeignService) {
        this.saTokenDaoRedisJackson = saTokenDaoRedisJackson;
        this.authUserFeignService = authUserFeignService;
    }

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 1.缓存中取
        List<String> permissions = JSONUtil.parseArray(
                saTokenDaoRedisJackson.stringRedisTemplate
                .opsForHash()
                .get(AuthRedisKey.permissions_cache_key.keyStyle(), loginId.toString()))
                .toList(String.class);

        // 2.没有就从数据库中取
        if (Func.isBlack.test(permissions)) {
            permissions = authUserFeignService.findResourceCodeByUserId(loginId).serviceData();
            saTokenDaoRedisJackson.stringRedisTemplate
                    .opsForHash()
                    .put(AuthRedisKey.permissions_cache_key.keyStyle(), loginId.toString(), JSONUtil.toJsonPrettyStr(permissions));
        }

        return permissions;
    }

    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 1.缓存中取
        List<String> roles = JSONUtil.parseArray(
                saTokenDaoRedisJackson.stringRedisTemplate
                .opsForHash()
                .get(AuthRedisKey.role_cache_key.keyStyle(), loginId.toString()))
                .toList(String.class);

        // 2.没有就从数据库中取
        if (Func.isBlack.test(roles)) {
            roles = authUserFeignService.findUserRoleByUserId(loginId).serviceData();
            saTokenDaoRedisJackson.stringRedisTemplate
                    .opsForHash()
                    .put(AuthRedisKey.role_cache_key.keyStyle(), loginId.toString(), JSONUtil.toJsonPrettyStr(roles));
        }

        return roles;
    }

}